package com.swd.order.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.Page;
import com.swd.order.Enums.OrderEnum;
import com.swd.order.model.Order;
import com.swd.order.model.OrderCommitModel;
import com.swd.order.model.User;
import com.swd.order.service.OrderService;
import com.swd.order.service.UserService;
import com.swd.order.service.WxService;
import com.swd.order.util.PageVo;
import com.swd.order.util.WxProperties;
import com.swd.order.vo.FoodsVo;
import com.swd.order.vo.OrderVo;
import com.swd.order.vo.Ret;
import com.swd.order.vo.Rets;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@RequestMapping("order")
@Slf4j
public class OrderController {

    @Autowired
    private WxService wxService;
    @Autowired
    private UserService userService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;
    @Autowired
    private TransactionDefinition transactionDefinition;
    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private WxProperties wxProperties;


    @PostMapping("save")
    public Ret save(@RequestBody OrderCommitModel order) throws JsonProcessingException, ParseException {

        log.info("订单消息:{}", objectMapper.writeValueAsString(order));


        if (StringUtils.isEmpty(order.getOrder().getOpenId())) {
            log.error("获取openId失败");
            return Rets.failure("处理订单失败");
        }

        User user = userService.getUserByOpenId(order.getOrder().getOpenId());

        if (user == null) {
            user = userService.register(order.getOrder().getOpenId(), order.getOrder().getUsername(), order.getOrder().getPhoto());
        }

        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);


        Order orderBase = null;
        Integer orderId;
        try {
            if (order.getOrder().isExtraMeal()){
                orderId = order.getOrder().getExtraMealId();
                orderBase = orderService.queryOrderById(order.getOrder().getExtraMealId());
                orderService.extraOrderSave(order);
            }else {
                orderId = orderService.orderSave(order, user.getId());
            }
        } catch (Exception e) {
            dataSourceTransactionManager.rollback(transactionStatus);
            log.error("订单保存失败", e);
            return Rets.failure(e.getMessage());
        }

        dataSourceTransactionManager.commit(transactionStatus);
        log.info("下单成功,开始推送");

        OrderCommitModel.OrderBean.DetailBean detail = order.getOrder().getDetail();

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");

        log.info("推送给下单人");
        Map<String, String> map = new HashMap<>();


        map.put("time4", simpleDateFormat.format(System.currentTimeMillis()));

        Date date;
        if (order.getOrder().isExtraMeal()){
//            Date parse = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(order.getOrder().getDetail().getDate());
            date=orderBase.getMealTime();
//            map.put("date8", simpleDateFormat.format(orderBase.getMealTime()));
        }else {
            date= new Date(Long.parseLong(order.getOrder().getDetail().getDate()));
//            map.put("date8", simpleDateFormat.format(new Date(Long.parseLong(order.getOrder().getDetail().getDate()))));
        }
        map.put("date8", simpleDateFormat.format(date));

        map.put("thing2", "请单击进入小程序查看");

        map.put("thing9", String.format("%s、%s、%s人、%s道菜、%s、%s",
                detail.getFlavorName(), detail.getPlaceName(), detail.getNum(), detail.getFoodsNum(),new SimpleDateFormat("E").format(date),order.getOrder().getDetail().getMealType()));

        wxService.subscribeMessageSend(orderId, user.getOpenid(), wxProperties.getCreateNotifyTemplate(), map);

        log.info("开始推送给行政与大厨");
        List<User> notifyUser = userService.getCreateNotifyUser();
        String jxAccessToken = wxService.getJXAccessToken();

        User finalUser = user;
        notifyUser.forEach(item -> {
            wxService.sendCreateMessage(finalUser, item, order.getOrder().getDetail().getRemark(), jxAccessToken, orderId);
        });
        return Rets.success(orderService.queryById(orderId),"订单提交成功");
    }


    @RequestMapping("{id}")
    public Ret queryById(@PathVariable int id) {
        OrderVo orderVo = orderService.queryById(id);
        int sum = orderVo.getFoods().stream().mapToInt(FoodsVo::getNum).sum();
        orderVo.setSum(sum);
        return Rets.success(orderService.queryById(id));
    }


    @PostMapping("all")
    public Ret getMealIng(@RequestParam(defaultValue = "1", required = false) int page,
                          @RequestParam(defaultValue = "5", required = false) int limit) {

        Page<OrderVo> orderVos = orderService.queryAll(page, limit);

        orderVos.getResult().forEach(item->{
            item.setSum(item.getFoods().stream().mapToInt(FoodsVo::getNum).sum());
        });

        return Rets.success(PageVo.build(orderVos));
    }


    @GetMapping("notify/{id}")
    public Ret orderNoftify(@PathVariable int id) {

        Order order = orderService.queryOrderById(id);

        if (order == null) {
            return Rets.failure("订单不存在");
        }

        if (order.getStatus() != OrderEnum.CREATE.getByteCode()) {
            return Rets.failure("订单异常");
        }

        log.info("修改订单状态->meal");
        order.setStatus(OrderEnum.MEAL.getByteCode());
        order.setNotifyTime(new Date());
        int i = orderService.update(order);
        if (i != 1) {
            return Rets.failure("处理订单失败");
        }

        User user = userService.queryById(order.getUserId());


        log.info("通知点餐人就餐");

        Map<String, String> map = new HashMap<>();
        map.put("thing3", "已准备就绪，可以用餐了。");
        map.put("date1", new SimpleDateFormat("yyyy-MM-dd hh:mm").format(order.getMealTime()));

        wxService.subscribeMessageSend(order.getId(), user.getOpenid(), wxProperties.getMealNotifyTemplate(), map);

        log.info("就餐通知行政");
        String jxAccessToken = wxService.getJXAccessToken();
        List<User> users = userService.getMealNotifyUser();

        users.forEach(item -> {
            wxService.sendMealMessage(item.getNotifyOpenid(), jxAccessToken, order.getId());
        });

        return Rets.success();
    }


    @GetMapping("finish/{id}")
    public Ret orderFinish(@PathVariable int id) {

        Order order = orderService.queryOrderById(id);

        if (order == null) {
            return Rets.failure("无效订单");
        }
        order.setStatus(OrderEnum.FINISH.getByteCode());
        order.setFinishTime(new Date());
        orderService.update(order);

        return Rets.success("操作成功");
    }

    @GetMapping("getAddMealOrder")
    public Ret getAddMealOrder() {
        List<OrderVo> orders = orderService.queryOrderVoAddMealEnable();

        if (orders.size()==0){
            return Rets.failure("无进行中订单");
        }

        orders.forEach(item->{
            item.setSum(item.getFoods().stream().mapToInt(FoodsVo::getNum).sum());
        });
        return Rets.success(orders);
    }
}
